#include "YangEdit.h"
#include <Qsci/qscilexercpp.h>
#include <Qsci/qsciscintillabase.h>
#include <QtDebug>

//extern "C" void ParserC(const char* name);
inline int GetMixCount(int Max,int Size)
{
	return Max>=Size?Size:Max;
}

YangEdit::YangEdit(QWidget* parent ):QMainWindow(parent)
{
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
	ui.setupUi(this);
    ConfPath = qgetenv("HOME")+confpath;
    QDir dir(qgetenv("HOME")+"/.qnotepad");
    if(!dir.exists())
    {
        dir.mkdir(qgetenv("HOME")+"/.qnotepad");
    }
	FindDirDialog = new FindDir(this);
	ChooseFileDialog = new ChooseFile(this);
    OptionDialog = new Option(this);
    FileTab = new TabWidget(this);
	FindText = new dlgFindText(this);
	ReplaceText = new ReplaceTextDialog(this);
	RecentMenu = new QMenu(this);
    FileTab->setObjectName(QString::fromUtf8("FileTab"));
    FileTab->setGeometry(QRect(0, 0, Width, Height));
    setCentralWidget(FileTab);
	CreateActions();
	LoadFile(untitle);
	GetRecentOpenFile();
	isCollapse = isFoldAll = isFullScreenFull = false;
	ui.actionRecentOpen->setMenu(RecentMenu);
	ui.actionInsertTab->setShortcut(tr("Tab"));
	ui.actionRemoveTab->setShortcut(tr("Shift+Tab"));
	ui.actionFindFile->setEnabled(false);
	LineIndex = new QLabel(statusBar());
	LineIndex->setAlignment(Qt::AlignHCenter);
	LineIndex->setIndent(100);
	statusBar()->addWidget(LineIndex);
	FileTree = NULL;
    rclxml* ProConfig = new rclxml(this);
}

YangEdit::~YangEdit()
{
    qDebug()<<"~YangEdit";
//    QSettings qs;
//    const char* path = "/home/yang/qs.ini";
//   // QsciLexer * Lexer =  const_cast<QsciLexer*>(TextEdit->lexer());
//    if(TextEdit->lexer()->language() == "C++")
//    {
//        qDebug()<<"writeSettings";
//        TextEdit->lexer()->writeSettings(qs,path);
//    }
//    if (Lexer!=NULL)
//    {
//        qDebug()<<"writeSettings";
//            Lexer->readSettings(qs,path);
//            Lexer->writeSettings(qs,path);
//    }
    qDebug()<<ConfPath;
    QSettings* Recent = new QSettings(ConfPath,QSettings::NativeFormat);
	Recent->beginGroup("RecentFileInfo");
	int MaxRecentFileCount = Recent->value("MaxRecentFileCount",10).toInt();
	Recent->beginGroup("RecentFileName");
    MaxRecentFileCount = GetMixCount(MaxRecentFileCount,RecentFileList.size());
	for(int i = 0;i < MaxRecentFileCount;i++)
	{
		Recent->setValue(QString::number(i),RecentFileList[i].filePath());
	}
	Recent->endGroup();
	Recent->endGroup();	
	
	delete Recent;
	delete FindDirDialog;
    delete FileTab;
	delete FindText;
	delete ReplaceText;
	if(FileTree!= NULL)
		delete FileTree;
}

void YangEdit::ShowFindTextDialog(void)
{
	FindText->SetTextEdit(TextEdit);
	FindText->exec();
}

void YangEdit::ShowReplaceTextDialog(void)
{
	ReplaceText->SetTextEdit(TextEdit);
	ReplaceText->exec();
}

void YangEdit::ShowGoToLineDialog(void)
{
	GoToLineDialog = new GoToLine(this);
	GoToLineDialog->SetTextEdit(TextEdit);
	GoToLineDialog->exec();
}
void YangEdit::CreateActions(void)
{
	connect(ui.actionUseCodeFolding,SIGNAL(triggered()),this,SLOT(CodeFolding()));
	connect(ui.actionShowEndLine, SIGNAL(toggled(bool)), this, SLOT(SetEolVisibility(bool)));
	connect(ui.actionOpen,SIGNAL(triggered()),this,SLOT(Open()));
	connect(ui.actionQuit, SIGNAL( triggered() ), this, SLOT( close() ) );
	connect(ui.actionNew, SIGNAL( triggered() ), this, SLOT( NewFile() ) );
	connect(ui.actionSave, SIGNAL( triggered() ), this, SLOT( Save() ) );
	connect(ui.actionSave_as, SIGNAL( triggered() ), this, SLOT( SaveAs() ) );
	connect(ui.actionAbout, SIGNAL( triggered() ), this, SLOT( About() ) );
	connect(ui.actionFindInDir,SIGNAL(triggered()),FindDirDialog,SLOT(exec()));
	connect(ui.actionFindText,SIGNAL(triggered()),this,SLOT(ShowFindTextDialog()));
	connect(ui.actionGoToLine,SIGNAL(triggered()),this,SLOT(ShowGoToLineDialog()));
	connect(ui.actionReplace,SIGNAL(triggered()),this,SLOT(ShowReplaceTextDialog()));
	connect(FileTab, SIGNAL(CreateNewFile() ), this, SLOT( NewFile() ) );
	connect(FileTab, SIGNAL(TabSaveFile()),this, SLOT(Save()));
	connect(FindDirDialog, SIGNAL(SendFileName(QString)),this, SLOT(LoadFile(QString)));
	connect(FindDirDialog, SIGNAL(SendFileName(QString,int)),this, SLOT(LoadFile(QString,int)));
	connect(ui.actionFindNext, SIGNAL(triggered()),FindText, SLOT(FindNext()));
	connect(ui.actionFindPrevious, SIGNAL(triggered()),FindText, SLOT(FindPrevious()));
	connect(RecentMenu, SIGNAL(triggered(QAction *)), this, SLOT(OpenRecent(QAction *)));
	connect(ui.menuLineEndings, SIGNAL(triggered(QAction *)), this, SLOT(SetEolType(QAction *)));
	connect(ui.menuHighLight, SIGNAL(triggered(QAction *)), this, SLOT(SetHightLight(QAction *)));
	connect(this, SIGNAL(SendCloseAllTab()), FileTab, SLOT(CloseAllTab()));
	connect(ui.actionZoomIn,SIGNAL(triggered()),this,SLOT(ZoomIn()));
	connect(ui.actionZoomOut,SIGNAL(triggered()),this,SLOT(ZoomOut()));
	connect(ui.actionWrap,SIGNAL(triggered()),this,SLOT(Wrap()));
	connect(ui.actionFullScreenMode,SIGNAL(triggered()),this,SLOT(ShowFullScreen()));
	connect(ui.actionSetReadOnly,SIGNAL(triggered()),this,SLOT(SetReadOnly()));
	connect(ui.actionClearReadOnlyFlag,SIGNAL(triggered()),this,SLOT(SetReadOnly()));
	connect(ui.actionFoldAll,SIGNAL(triggered()),this,SLOT(FoldAll()));
	connect(ui.actionUnFoldAll,SIGNAL(triggered()),this,SLOT(UnFoldAll()));
	connect(ui.actionCollapseTheCurrentLevel,SIGNAL(triggered()),this,SLOT(Collapse()));
	connect(ui.actionUncollapseTheCurrentLeve,SIGNAL(triggered()),this,SLOT(UnCollapse()));
	connect(ui.actionGoToMacthingBrace,SIGNAL(triggered()),this,SLOT(GoToMacthingBrace()));
	connect(ui.actionInsertTab,SIGNAL(triggered()),this,SLOT(InsertTab()));
	connect(ui.actionRemoveTab,SIGNAL(triggered()),this,SLOT(RemoveTab()));
	connect(ui.actionDumplicateCurrentLine,SIGNAL(triggered()),this,SLOT(DumplicateLine()));
	connect(ui.actionMoveUpCurrentLine,SIGNAL(triggered()),this,SLOT(MoveUpCurrentLine()));
	connect(ui.actionMoveDownCurrentLine,SIGNAL(triggered()),this,SLOT(MoveDownCurrentLine()));
	connect(ui.actionToUpperCase,SIGNAL(triggered()),this,SLOT(ToUpper()));
	connect(ui.actionToLowerCase,SIGNAL(triggered()),this,SLOT(ToLower()));
	connect(ui.actionBlockToggleComment,SIGNAL(triggered()),this,SLOT(BlockToggleComment()));
	connect(ui.actionBlockUnComment,SIGNAL(triggered()),this,SLOT(BlockUnComment()));
	connect(ui.actionBlockStream,SIGNAL(triggered()),this,SLOT(BlockStream()));
	connect(ui.actionCut,SIGNAL(triggered()),this,SLOT(Cut()));
	connect(ui.actionCopy,SIGNAL(triggered()),this,SLOT(Copy()));
	connect(ui.actionPaste,SIGNAL(triggered()),this,SLOT(Paste()));
	connect(ui.actionDelete,SIGNAL(triggered()),this,SLOT(RemoveSelectedText ()));
	connect(ui.actionRedo,SIGNAL(triggered()),this,SLOT(Redo()));
	connect(ui.actionUndo,SIGNAL(triggered()),this,SLOT(Undo()));
	connect(ui.actionSelect_All,SIGNAL(triggered()),this,SLOT(SelectAll()));
	connect(FileTab, SIGNAL(currentChanged (int)),this, SLOT(ChangeTab(int)));
	connect(ui.actionNewProject, SIGNAL(triggered()),this, SLOT(NewProject()));
	connect(ui.actionOpenProject, SIGNAL(triggered()),this,SLOT(OpenProject()));
	connect(ui.actionFindFile,SIGNAL(triggered()),this,SLOT(ShowChooseFile()));
    connect(ui.actionOption,SIGNAL(triggered()),this,SLOT(ShowOption()));
	connect(ChooseFileDialog,SIGNAL(LoadCode(const QString&)),this,SLOT(LoadFile(QString)));
    connect(ui.actionAddDirs,SIGNAL(triggered()),this,SLOT(AddDirs()));
    connect(ui.actionAddFiles,SIGNAL(triggered()),this,SLOT(AddFiles()));
    connect(ui.actionCloseProject,SIGNAL(triggered()),this,SLOT(CloseProject()));
}

void YangEdit::OpenIncludeFile(const QString& FileName)
{
	if(FileTree!=NULL)
	{
		QStringList FileList = FileTree->find(FileName);
		if(FileList.isEmpty())
		{
			QMessageBox::warning(this, SoftwareName,
                             tr("Cannot Open Include file: %1\n").arg(FileName));
		}
		else if(FileList.size()== 1)
		{
			LoadFile(FileList[0]);
		}	
		else if(FileList.size()>1)
		{
			//prompt info;
		}
	}
	else
	{
			QMessageBox::warning(this, SoftwareName,
                             tr("Cannot Open Include file: %1\n").arg(FileName));
	}
}

void YangEdit::BlockToggleComment()
{
	QString Ext = GetExt(CurFileName);
	if(Ext == "cpp" || Ext == "c" || Ext == "php" || Ext == "cxx")
	{
		CommentLineC();
	}	
}
void YangEdit::CommentLineC()
{
		int Line,index;
		TextEdit->getCursorPosition(&Line,&index);
		QString LineText = TextEdit->text(Line);
		bool FindComment = false;
		for(register int i = 0;(i+1)<TextEdit->lineLength(Line);i++)
		{
			if(LineText[i] == '/' && LineText[i+1] == '/')
			{
				FindComment = true;
				TextEdit->setSelection(Line,i,Line,i+2);
				TextEdit->removeSelectedText();
				return ;
			}
		}
		if(!FindComment)
		{
			TextEdit->insertAt("//",Line,index);
		}
}

void YangEdit::BlockComment()
{
	QString Ext = GetExt(CurFileName);
	if(Ext == "cpp" || Ext == "c" || Ext == "php" || Ext == "cxx")
	{
		CommentC();
	}	
}

void YangEdit::CommentC()
{
	int lineFrom,indexFrom,lineTo,indexTo;
        TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
	for(register int i=lineFrom;i<=lineTo;i++)
	{
		if(i==lineFrom)
		{
			TextEdit->insertAt("//",i,indexFrom);
		}
		else
		{
			TextEdit->insertAt("//",i,0);
		}
	}
}

void YangEdit::UnCommentC()
{
	if(TextEdit->hasSelectedText())
	{		
		int lineFrom,indexFrom,lineTo,indexTo;
		TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
		bool IsStreamComment = false;
		for(register int i = lineFrom; i<=lineTo; i++)
		{
			QString LineText = TextEdit->text(i);
			if(i == lineFrom)
			{
				for(register int j = indexFrom;(j+1)<TextEdit->lineLength(i);j++)
				{
					if(LineText[j]=='/' && LineText[j+1] == '/')
					{
						TextEdit->setSelection(i,j,i,j+2);
						TextEdit->removeSelectedText();
						break;
					}
					else if(LineText[j] == '/' && LineText[j+1] == '*')
					{
						TextEdit->setSelection(i,j,i,j+2);
						TextEdit->removeSelectedText();
						IsStreamComment = true; 
					}
				}
			}
			else
			{
				if(!IsStreamComment)
				{
					QString LineText = TextEdit->text(i);
					for(register int j = 0;(j+1)< TextEdit->lineLength(i);j++)
					{
						if(LineText[j]=='/' && LineText[j+1] == '/')
						{	
							TextEdit->setSelection(i,j,i,j+2);
							TextEdit->removeSelectedText();
							break;
						}	
					}	
				}
				else
				{
					for(register int j = 0;(j+1)< TextEdit->lineLength(i);j++)
					{
						if(LineText[j] == '*' && LineText[j+1] == '/')
						{
							TextEdit->setSelection(i,j,i,j+2);
							TextEdit->removeSelectedText();
							return ;
						}
					}
				}
			}
		}
	}	
	else
        {
		 int Line,index;
		 TextEdit->getCursorPosition(&Line,&index);
                  QString LineText = TextEdit->text(Line);
                 for(int i=0;(i+1)<TextEdit->lineLength(Line);i++)
                 {
                             if(LineText[i] == '/' && LineText[i+1] == '/')
                             {
					 TextEdit->setSelection(Line,i,Line,i+2);
					 TextEdit->removeSelectedText();                           
                              } 
                  }					 
         } 			
}

void YangEdit::BlockUnComment()
{
	QString Ext = GetExt(CurFileName);
	if(Ext == "cpp" || Ext == "c" || Ext == "php" || Ext == "cxx")
	{
		UnCommentC();
	}	
}

void YangEdit::BlockStreamC()
{
	int lineFrom,indexFrom,lineTo,indexTo;
        TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
	TextEdit->insertAt("/*",lineFrom,indexFrom);
	TextEdit->insertAt("*/",lineTo,indexTo);
}

void YangEdit::BlockStream()
{
	QString Ext = GetExt(CurFileName);
	if(Ext == "cpp" || Ext == "c" || Ext == "php" || Ext == "cxx")
	{
		BlockStreamC();
	}	
}

void YangEdit::ToUpper()
{
	int lineFrom,indexFrom,lineTo,indexTo;
        TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
	QString UpperText = TextEdit->selectedText().toUpper();
	TextEdit->removeSelectedText();
	TextEdit->insertAt(UpperText,lineFrom,indexFrom);
}

void YangEdit::ToLower()
{
	int lineFrom,indexFrom,lineTo,indexTo;
        TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
	QString LowerText = TextEdit->selectedText().toLower();
	TextEdit->removeSelectedText();
	TextEdit->insertAt(LowerText,lineFrom,indexFrom);
}

void YangEdit::MoveUpCurrentLine()
{
	int Line,Index,LineLength;
	QString LineText;
	TextEdit->getCursorPosition(&Line,&Index);
	if(Line == 0)
		return;
	LineText = TextEdit->text(Line);
	LineLength = TextEdit->lineLength(Line);
	TextEdit->setSelection(Line,0,Line,LineLength);
	TextEdit->removeSelectedText();
	TextEdit->insertAt(LineText,(Line-1),0);
	TextEdit->setCursorPosition((Line-1),0);
}

void YangEdit::MoveDownCurrentLine()
{
	int Line,Index,LineLength;
	QString LineText;
	TextEdit->getCursorPosition(&Line,&Index);
	if(Line > TextEdit->lines())
		return ;
	LineText = TextEdit->text(Line);
	LineLength = TextEdit->lineLength(Line);
	TextEdit->setSelection(Line,0,Line,LineLength);
	TextEdit->removeSelectedText();
	TextEdit->insertAt(LineText,(Line+1),0);
	TextEdit->setCursorPosition((Line+1),0);
}

void YangEdit::DumplicateLine()
{
	int Line,Index;
	QString LineText;
	TextEdit->getCursorPosition(&Line,&Index);
	LineText = TextEdit->text(Line);
	TextEdit->insertAt(LineText,(Line+1),0);
}

void YangEdit::InsertTab()
{
        if(TextEdit->hasSelectedText())
        {
		int lineFrom,indexFrom,lineTo,indexTo;
		TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
		for(int i =lineFrom; i<=lineTo ; i++)
		{
			TextEdit->indent(i);
		}
         }
         else
         {
		
                        int Line,index;
                        TextEdit->getCursorPosition(&Line,&index);
                        TextEdit->indent(Line);
                        //TextEdit->setCursorPosition(Line,index+8);  
          }   
}

void YangEdit::RemoveTab()
{
        if(TextEdit->hasSelectedText())
        { 
		int lineFrom,indexFrom,lineTo,indexTo;
		TextEdit->getSelection(&lineFrom,&indexFrom,&lineTo,&indexTo);
		for(int i =lineFrom; i<=lineTo ; i++)
		{
			TextEdit->unindent(i);
		}
         }
        else
        {
			int Line,index;
                        TextEdit->getCursorPosition(&Line,&index);
                        TextEdit->unindent(Line); 
        }
}

void YangEdit::GoToMacthingBrace()
{
	TextEdit->moveToMatchingBrace();
}

void YangEdit::SetFoldStyle()
{
	//QsciScintilla::FoldStyle state =  QsciScintilla::BoxedTreeFoldStyle;
	Scintilla::FoldStyle state =  Scintilla::BoxedTreeFoldStyle;
	TextEdit->setFolding(state);
}

void YangEdit::Collapse()
{
	if(!isCollapse)
	{
		SetFoldStyle();
		int CurrLine;
		int CurrIndex;
		TextEdit->getCursorPosition(&CurrLine,&CurrIndex);
		TextEdit->foldLine(CurrLine);
		isCollapse = true;
	}		
}

void YangEdit::UnCollapse()
{
	if(isCollapse)
	{
		SetFoldStyle();
		int CurrLine;
		int CurrIndex;
		TextEdit->getCursorPosition(&CurrLine,&CurrIndex);
		TextEdit->foldLine(CurrLine);
		isCollapse = false;
	}
}

void YangEdit::FoldAll()
{
        if(!isFoldAll)
	{
		SetFoldStyle();
		isFoldAll = true;
		TextEdit->foldAll();
		ui.actionUseCodeFolding->setChecked(true);
	}
}

void YangEdit::UnFoldAll()
{
        if(isFoldAll)
	{
		SetFoldStyle();
		TextEdit->foldAll();
		isFoldAll = false;
	}
}

void YangEdit::SetReadOnly()
{
	if(!TextEdit->isReadOnly())
		TextEdit->setReadOnly(true);	
	else
		TextEdit->setReadOnly(false);
}

void YangEdit::ShowFullScreen()
{
	if(!isFullScreenFull)
	{
		this->showFullScreen();
		isFullScreenFull = true;
		QDesktopWidget *Desktop = QApplication::desktop();
        TextEdit->setGeometry(QRect(0, 0,Desktop->width(), Desktop->height()));
        FileTab->setGeometry(QRect(0, 0,Desktop->width(), Desktop->height()));
		ui.actionFullScreenMode->setIcon(QIcon(TickPngPath));
	}
	else
	{
        TextEdit->setGeometry(QRect(0, 0, Width, Height));
        FileTab->setGeometry(QRect(0, 0,Width, Height));
		isFullScreenFull = false;
		this->showNormal();
		ui.actionFullScreenMode->setIcon(QIcon());
	}
}

void YangEdit::Wrap()
{
	if(!TextEdit->wrapMode())
	{
		//TextEdit->setWrapMode(QsciScintilla::WrapWord);		
		TextEdit->setWrapMode(Scintilla::WrapWord);		
		ui.actionWrap->setIcon(QIcon(TickPngPath));
	
	}
	else
	{
		//TextEdit->setWrapMode(QsciScintilla::WrapNone);		
		TextEdit->setWrapMode(Scintilla::WrapNone);		
		ui.actionWrap->setIcon(QIcon());
	}
}

void YangEdit::ZoomIn()
{
	TextEdit->zoomIn();
}

void YangEdit::ZoomOut()
{
	TextEdit->zoomOut();
}

void YangEdit::ChangeTab(int index)
{
    qDebug()<<"ChangeTab";
	FileTab->setCurrentIndex(index);
	GetCurTextEdit();
	getCurrentFile();
	FindText->SetTextEdit(TextEdit);
}

void YangEdit::GetCurTextEdit(void)
{
	QWidget* Widget = FileTab->currentWidget();
       // TextEdit = Widget->findChild<QsciScintilla*>();
        TextEdit = Widget->findChild<Scintilla*>();
	Q_ASSERT(TextEdit!=NULL);
}
void YangEdit::Redo()
{
	TextEdit->redo();
}

void YangEdit::Copy()
{
	TextEdit->copy();
}

void YangEdit::Cut()
{
	TextEdit->cut();
}

void YangEdit::Paste()
{
	TextEdit->paste();
}

void YangEdit::RemoveSelectedText()
{
	TextEdit->removeSelectedText();
}

void YangEdit::SelectAll()
{
	TextEdit->selectAll();
}


void YangEdit::CreateTabPage(void)
{
	CurrTab = new QWidget();
    CurrTab->setObjectName(QString::fromUtf8("tab"));
    CurrTab->setGeometry(QRect(0, 0, width(),height()));
    TextEdit = new Scintilla(CurrTab);
	Q_ASSERT(TextEdit!=NULL);
	TextEdit->setUtf8(true);
    TextEdit->setObjectName(QString::fromUtf8("TextEdit"));
    TextEdit->setGeometry(QRect(0, 0, width(),height()-DelHeight));

}

void YangEdit::Undo(void)
{
	TextEdit->undo();
	if ( !TextEdit->isUndoAvailable())
	{
		TabInfo* Temp = FileTab->GetCurTabInfo();
		QString ModifiedTag = tr("%1").arg(Temp->FileName);
		int index = FileTab->currentIndex();
		FileTab->setTabText(index,ModifiedTag);
		//QString ModifiedTag = tr("%1").arg(Temp->FileName);
	}
}

void YangEdit::NewFile()
{
    qDebug()<<"NewFile";
	LoadFile(untitle);
}

void YangEdit::Open()
{
    QString fileName = QFileDialog::getOpenFileName(this);
    qDebug()<<"Open File";
    if (!fileName.isEmpty())
	{
        LoadFile(fileName);
	    AddRecentOpenFile(fileName);	
	}
}

void YangEdit::closeEvent(QCloseEvent *event)
{
    Q_UNUSED(event);
    disconnect(FileTab, SIGNAL(currentChanged (int)),this, SLOT(ChangeTab(int)));
    disconnect(FileTab, SIGNAL(CreateNewFile() ), this, SLOT( NewFile() ) );
	emit SendCloseAllTab();	
}

void YangEdit::LoadFile(QString FileName,int LineNum)
{
	LoadFile(FileName);
	TextEdit->setCursorPosition(LineNum,0);   
}

void YangEdit::LoadFile(QString fn)
{
    qDebug()<<"LoadFile";
	QFile File(fn);
	CreateTabPage();
    FileTab->addTab(CurrTab, StrippedName(fn));
	FileTab->setCurrentWidget(CurrTab);
	if (fn == untitle)
	{
		TextEdit->clear();
	}
	else
	{
    		if (!File.open(QFile::ReadOnly))
	 	{
        		QMessageBox::warning(this, SoftwareName,
                             tr("Cannot read file %1:\n%2.")
                             .arg(fn)
                             .arg(File.errorString()));
        		return;
    		}
    		QTextStream in(&File);
            in.setCodec("UTF-8");
    		QApplication::setOverrideCursor(Qt::WaitCursor);
    		TextEdit->setText(in.readAll());
    		QApplication::restoreOverrideCursor();
	}
	//setCurrentFile(fn);
	FileTab->setTabInfo(fn);
	CurFileName = fn;
    QsciLexer * Lexer = GetLexerForDocument(fn);
	if (Lexer != NULL)
	{
        qDebug()<<"Lexer"<<fn;
		Lexer->setParent(TextEdit);
		TextEdit->setLexer(Lexer);
       // TextEdit->autoCompleteFromAll();
        TextEdit->setAutoCompletionSource(QsciScintilla::AcsAPIs);
        TextEdit->setAutoCompletionThreshold(1);
       // TextEdit->autoCompleteFromDocument();
	}
	SetTextEditConfig(TextEdit);
	TextEdit->setModified(false); 
	connect(TextEdit, SIGNAL(textChanged()),this, SLOT(DocumentWasModified()));
	connect(TextEdit, SIGNAL(selectionChanged()),this, SLOT(SelectText()));
    connect(TextEdit,SIGNAL(ToggleCommentSignal()),this,SLOT(BlockToggleComment()));
    connect(TextEdit,SIGNAL(BlockCommentSignal()),this,SLOT(BlockComment()));
    connect(TextEdit,SIGNAL(BlockStreamSignal()),this,SLOT(BlockStream()));
    connect(TextEdit,SIGNAL(UnCommentSignal()),this,SLOT(BlockUnComment()));
    connect(TextEdit,SIGNAL(cursorPositionChanged(int,int)),this,SLOT(StatusCursorPosition(int,int)));
	connect(TextEdit,SIGNAL(SendFileNameSignal(const QString&)),this,SLOT(OpenIncludeFile(const QString&)));
}

void YangEdit::SelectText()
{
	if(TextEdit->hasSelectedText())
	{
		ui.actionBlockUnComment->setEnabled(true);
        ui.actionBlockComment->setEnabled(true);
        ui.actionBlockStream->setEnabled(true);
		ui.actionToUpperCase->setEnabled(true);
        ui.actionToLowerCase->setEnabled(true);
	}
	else
	{
		ui.actionBlockUnComment->setEnabled(false);
        ui.actionBlockComment->setEnabled(false);
        ui.actionBlockStream->setEnabled(false);
		ui.actionToUpperCase->setEnabled(false);
        ui.actionToLowerCase->setEnabled(false);
	}
}

bool YangEdit::Save()
{
	if(CurFileName == untitle)
	{
		return SaveAs();	
	}
	else
	{
		return SaveFile(CurFileName);
	}
}
 
bool YangEdit::SaveAs()
{
	QString FileName = QFileDialog::getSaveFileName(this,tr("Save As"));
	return SaveFile(FileName);
}

bool YangEdit::SaveFile(const QString& FileName)
{
    qDebug()<<"SaveFile";
	QFile File(FileName);
    	if (!File.open(QFile::WriteOnly)) 
	{
        	QMessageBox::warning(this, SoftwareName,
                             tr("Cannot write file %1:\n%2.")
                             .arg(FileName)
                             .arg(File.errorString()));
        	return false;
    	}
	AddRecentOpenFile(FileName);
	int index = FileTab->currentIndex();
	FileTab->setTabText(index,StrippedName(FileName));
	GetCurTextEdit();
    QApplication::setOverrideCursor(Qt::WaitCursor);
    QTextStream fd(&File);
	fd.setCodec("UTF-8");
    fd<<TextEdit->text();
    QApplication::restoreOverrideCursor();
	FileTab->setTabInfo(FileName);
	CurFileName = FileName;
	TextEdit->setModified(false);
	//setCurrentFile(FileName);
	return true;
}

void YangEdit::About()
{
	 QMessageBox::about(this, tr("About QNotepad"),
            tr("The <b>QNotepad</b> is a Program Source Edit .<br>"
        " Author :ywchen2000 <br>"
		" E-mail:ywchen2000@gmail.com"));

}

void YangEdit::getCurrentFile(void)
{
	TabInfo* temp = FileTab->GetCurTabInfo();
	if(temp == NULL)
	{
		CurFileName =untitle;
	}
	else
	{
		CurFileName = temp->FileName;
	}
}

void YangEdit::DocumentWasModified()
{
	TabInfo* Temp = FileTab->GetCurTabInfo();
	Q_ASSERT(Temp!=NULL);
	if(TextEdit->isModified())
	{
		QString ModifiedTag = tr("%1*").arg(Temp->FileName);
		int index = FileTab->currentIndex();
		FileTab->setTabText(index,ModifiedTag);
		setWindowTitle(tr("%1 - %2").arg(Temp->DirName).arg(SoftwareName));
	}
}

QString YangEdit::StrippedName(const QString &fullFileName)
{
    	return QFileInfo(fullFileName).fileName();
}

bool YangEdit::MayBeSave()
{
    	return true;
}

void YangEdit::GetRecentOpenFile(void)
{
    qDebug()<<"GetRecentOpenFile"<<ConfPath;
	QSettings Recent(ConfPath,QSettings::NativeFormat);
	Recent.beginGroup("RecentFileInfo");
	int MaxRecentFileCount = Recent.value("MaxRecentFileCount",MAXRECENTFILECOUNT).toInt();
	Recent.beginGroup("RecentFileName");
	QStringList FileNameIndex = Recent.allKeys();
    MaxRecentFileCount = GetMixCount(MaxRecentFileCount,FileNameIndex.size());
    qDebug()<<"MaxRecentFileCount"<<MaxRecentFileCount;

	for ( int i = 0 ; i<MaxRecentFileCount;i++)
	{
        RecentFileList.push_back(Recent.value(FileNameIndex.at(i)).toString());
	}
	Recent.endGroup();
    //Recent.endGroup();
  	RecentMenu->clear();
  	for (int i = 0; i < MaxRecentFileCount; ++i)
  	{
        if(RecentFileList[i].canonicalFilePath().isEmpty())
        {
            continue;
        }
        else
            DealAction(RecentFileList[i].canonicalFilePath());
	}
}

void YangEdit::AddRecentOpenFile(const QString& FileName)
{
    qDebug()<<"AddRecentOpenFile"<<ConfPath;
	QSettings Recent(ConfPath,QSettings::NativeFormat);	
	QFileInfo AddFile = QFileInfo(FileName);
	Recent.beginGroup("RecentFileInfo");
	int MaxRecentFileCount = Recent.value("MaxRecentFileCount",MAXRECENTFILECOUNT).toInt();
	Recent.endGroup();
    qDebug()<<"RecentFile:"<<RecentFileList.size();
	for (int i = 0; i < RecentFileList.size(); i++) 
	{
            if (RecentFileList[i].canonicalFilePath() == AddFile.canonicalFilePath() || !(RecentFileList[i].exists() && RecentFileList[i].isFile()))
            {
                    qDebug()<<"RecentFileList"<<RecentFileList[i].canonicalFilePath();
                    RecentFileList.removeAt(i--);
            }
    }
  	RecentMenu->clear();
	RecentFileList.push_front(AddFile);
    MaxRecentFileCount = GetMixCount(MaxRecentFileCount,RecentFileList.size());
    qDebug()<<"MaxRecentFileCount"<<MaxRecentFileCount;
  	for (int i = 0; i < MaxRecentFileCount; ++i)
  	{
		DealAction(RecentFileList[i].canonicalFilePath());
	}	
}

void YangEdit::DealAction(const QString& FileName)
{
    qDebug()<<"FileName:"<<FileName;
    QAction* Action = RecentMenu->addAction( StrippedName(FileName));
	Action->setStatusTip( FileName );
}

void YangEdit::OpenRecent(QAction* Action)
{
	LoadFile(Action->statusTip());
}

void YangEdit::CodeFolding(void)
{
	//QsciScintilla::FoldStyle state = static_cast<QsciScintilla::FoldStyle>((!TextEdit->folding()) * 5);
	Scintilla::FoldStyle state = static_cast<Scintilla::FoldStyle>((!TextEdit->folding()) * 5);
	TextEdit->setFolding(state);
}

void YangEdit::SetEolVisibility(bool val)
{
	TextEdit->setEolVisibility(val);
}

void YangEdit::SetEolType(QAction* type)
{
	QList<QAction*> ActionList = ui.menuLineEndings->actions();
	for(register int i=0 ; i< ActionList.size();i++)
	{
		if(ActionList[i] == type)
		{
			switch(i)
			{
				case Unix:
					//TextEdit->setEolMode(QsciScintilla::EolUnix);
					TextEdit->setEolMode(Scintilla::EolUnix);
					break;
				case Windows:
					//TextEdit->setEolMode(QsciScintilla::EolWindows);
					TextEdit->setEolMode(Scintilla::EolWindows);
					break;
				case Mac:
					//TextEdit->setEolMode(QsciScintilla::EolMac);
					TextEdit->setEolMode(Scintilla::EolMac);
					break;
				default:
					break;
			}
			TextEdit->convertEols(TextEdit->eolMode());
			ActionList[i]->setIcon(QIcon(TickPngPath));
		}
		else
		{
			ActionList[i]->setIcon(QIcon());
		}

	}
}

void YangEdit::SetHightLight(QAction* Type)
{	
	QsciLexer* Lexer = NULL;
	QList<QAction*> ActionList = ui.menuHighLight->actions();
    QSettings qs;
	for(register int i = 0 ;i<ActionList.size();i++)
	{
		if( ActionList[i] == Type)
		{
			switch(i)
			{
				case Normal:
					Lexer = NULL;
					break;
				case Cpp:
					Lexer = new QsciLexerCPP();
					break;
				case Python:
					Lexer = new QsciLexerPython();
					break;
				case Java:
					Lexer = new QsciLexerJava();
					break;
				case Lua:
					Lexer = new QsciLexerLua();
					break;
				case XML:
					Lexer = new QsciLexerXML();
					break;
        			case Perl:
					Lexer = new QsciLexerPerl();
					break;
        			case PHP:
					Lexer = new QsciLexerCPP();
					break;
        			case Ruby:
					Lexer = new QsciLexerRuby();
					break;
        			case Javascript:
					Lexer = new QsciLexerJavaScript();
					break;
        			case HTML:
					Lexer = new QsciLexerHTML();
					break;
        			case SQL:
					Lexer = new QsciLexerSQL();
					break;
        			case CSS:
					Lexer = new QsciLexerCSS();
					break;
        			case Bash:
					Lexer = new QsciLexerBash();
					break;
				default:
					break;
			}
			QsciLexer* DeleteLexer = const_cast<QsciLexer*>(TextEdit->lexer());   
			delete DeleteLexer;
			if( Lexer != NULL)
			{
				Lexer->setParent(TextEdit);
				TextEdit->setLexer(Lexer);
			}
			else
				TextEdit->setLexer();
			ActionList[i]->setIcon(QIcon(TickPngPath));
		}
		else
			ActionList[i]->setIcon(QIcon());
	}
}

void YangEdit::StatusCursorPosition(int Line,int Index)
{
	LineIndex->setText(tr("Line: %1,Index: %2").arg((Line+1)).arg((Index+1)));
}

void YangEdit::ReadFileToTree(const QString& dir,tree* ATree)
{
	QDir Dir(dir);
	Dir.setFilter(QDir::AllEntries | QDir::NoDotAndDotDot);
    Dir.setSorting(QDir::Size | QDir::Reversed);

    QFileInfoList list = Dir.entryInfoList();
    for (int i = 0; i < list.size(); i++)
	{
        QFileInfo FileInfo = list.at(i);
		if(FileInfo.isDir())
		{
			ReadFileToTree(FileInfo.filePath(),ATree);
		}
		else if(FileInfo.isFile())
		{
			 //if(!FileInfo.isReadable())
        		// {
			//应该只能处理文本文件,非文本文件不能处理
		 		ATree->insert(FileInfo.filePath());
				//#########################################a
				//qDebug()<<FileInfo.filePath().toStdString().c_str()<<endl;
				QFile File(FileInfo.filePath());
				File.open(QFile::ReadOnly);
    				QTextStream in(&File);
				//in.setCodec("UTF-8");
				QString TextContext = in.readAll();
        		//}	
		}	
	}
//	delete MM;
}

bool YangEdit::event(QEvent *event)
{
    if(event->type() == QEvent::Resize)
    {
            if(TextEdit!= NULL)
            {
                TextEdit->setGeometry(QRect(0, 0, width(),height()-DelHeight));
                CurrTab->setGeometry(QRect(0, 0, width(),height()));
            }
    }
  return QMainWindow::event(event);
}

void YangEdit::CreateProjectFile()
{}

void YangEdit::AddFiles()
{
    if(FileTree == NULL)
        return ;
    QStringList filelist =  QFileDialog::getOpenFileNames(this,tr("Open Files"),
                                  qgetenv("HOME"));
    for(register int i=0;i<filelist.size();i++)
    {
        FileTree->insert(filelist[i]);
    }
}

void YangEdit::NewProject(void)
{
	QString dir = QFileDialog::getExistingDirectory(this, tr("Open Directory"),
                                                 qgetenv("HOME"),
                                                 QFileDialog::ShowDirsOnly
                                                 | QFileDialog::DontResolveSymlinks);
	// maybe change;
	if(FileTree!= NULL)
	{
        FileTree->close();
		delete FileTree;
	}
	FileTree = new tree();
	FileTree->init();
	ui.actionFindFile->setEnabled(true);
	ReadFileToTree(dir,FileTree);
    //ctags -R --fields=+aiKSzn
//    QDir projectdir(dir);
//    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("utf-8"));
//    QString ctagfile =  qgetenv("HOME") + "/.qnotepad/" + projectdir.dirName()+".ctag";
   // QString command = QString(" -R --fields=+aiKSzn −f")+ctagfile;
//    QProcess process;
//    QString program = "ctags";
//    QStringList args;
//    args<<QString("-R")<<QString("--fields=+aiKSzn")<<(QString("-f")+ctagfile)<<dir;
//    process.execute(program,args);
}

void YangEdit::OpenProject(void)
{
    NewProject();
}

void YangEdit::CloseProject(void)
{
    FileTree->close();
    FileTree = NULL;
}

void YangEdit::ShowChooseFile(void)
{
	ChooseFileDialog->GetTree(FileTree);
	ChooseFileDialog->exec();
}

void YangEdit::ShowOption()
{
    OptionDialog->exec();
}

void YangEdit::AddDirs()
{
    if(FileTree == NULL)
    {
        return ;
    }
    QString dir = QFileDialog::getExistingDirectory(this,"Open Dialog", qgetenv("HOME"), QFileDialog::ShowDirsOnly
                                      | QFileDialog::DontResolveSymlinks);
    ReadFileToTree(dir,FileTree);

}
//void YangEdit::CtagsFiles(const QString &ctags, const QString &dir)
//{}
